package application.mvc.sys.config.box;

import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

import com.jfinal.kit.StrKit;
import application.common.model.Board;
import application.common.model.Cabinet;
import application.common.render.BoardProperty;
import application.common.render.CabinetProperty;
import application.common.ui.ProgressStage;
import application.common.util.LayerUtil;
import application.common.util.RouteUtil;
import application.common.util.ShiroUtil;
import application.common.util.UuidUtil;
import javafx.animation.Animation;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.RotateTransition;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.util.Duration;

public class BoxController implements Initializable {

	@FXML
	private Label headerLabel;
	
	@FXML
	private Label copyrightLabel;
	
	@FXML
	private Label usernameLabel;
	
	@FXML
	private Label roleNameLabel;
	
	@FXML
	private ImageView portraitImageView;

	@FXML
	private TableView<CabinetProperty> boxTableView;
	
	@FXML
	private TableView<BoardProperty> boardTableView;

	@FXML
	private Pane timerOutLinePane;

	@FXML
	private Pane timerInLinePane;

	@FXML
	private Label timerLabel;
	private Timeline animation;
	private RotateTransition rotateTransitionOut;
	private RotateTransition rotateTransitionIn;

	private final ObservableList<CabinetProperty> data = FXCollections.observableArrayList();
	private final ObservableList<BoardProperty> boardData = FXCollections.observableArrayList();
	private boolean isDestroy=false;
	@SuppressWarnings("unchecked")
	public void initialize(URL location, ResourceBundle resources) {
		
		headerLabel.setText(ShiroUtil.getSoftName());
		copyrightLabel.setText(ShiroUtil.getCopyright());
		
		if(ShiroUtil.getUser()!=null) {
			portraitImageView.setImage(ShiroUtil.getUser().getPortrait());
			usernameLabel.setText(ShiroUtil.getUser().getName());
			roleNameLabel.setText(ShiroUtil.getUser().getRoleName());
		}
		
		boxTableView.setEditable(true);
		TableColumn<CabinetProperty, String> idColumn = new TableColumn<CabinetProperty, String>("标识");
		idColumn.setMinWidth(100);
		idColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("id"));
		idColumn.setVisible(false);

		TableColumn<CabinetProperty, String> nameColumn = new TableColumn<CabinetProperty, String>("名称");
		nameColumn.setMinWidth(60);
		nameColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("name"));
		nameColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		nameColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
					if (cabinet != null) {
						cabinet.setName(event.getNewValue());
						cabinet.update();
						event.getRowValue().setName(event.getNewValue());
					}
				}
			}
		});

		TableColumn<CabinetProperty, String> codeColumn = new TableColumn<CabinetProperty, String>("标识");
		codeColumn.setMinWidth(40);
		codeColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("code"));
		codeColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		codeColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
					if (cabinet != null) {
						cabinet.setCode(event.getNewValue());
						cabinet.update();
						event.getRowValue().setCode(event.getNewValue());
					}
				}
			}
		});

		TableColumn<CabinetProperty, String> typeColumn = new TableColumn<CabinetProperty, String>("规格");
		typeColumn.setMinWidth(40);
		typeColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("type"));
		typeColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		typeColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					if (StrKit.equals("1", event.getNewValue()) || StrKit.equals("2", event.getNewValue())
							|| StrKit.equals("3", event.getNewValue())) {
						Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
						if (cabinet != null) {
							cabinet.setType(event.getNewValue());
							cabinet.update();
							event.getRowValue().setType(event.getNewValue());
						}
					} else {
						LayerUtil.open("规格只能填（1，2，3）", 110);
						event.getRowValue().setType(event.getOldValue());
						boxTableView.refresh();
					}
				}
			}
		});

		TableColumn<CabinetProperty, String> totalColumn = new TableColumn<CabinetProperty, String>("容量");
		totalColumn.setMinWidth(40);
		totalColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("total"));

//		TableColumn<CabinetProperty, String> freeNumColumn = new TableColumn<CabinetProperty, String>("空闲");
//		freeNumColumn.setMinWidth(40);
//		freeNumColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("freeNum"));
//
//		TableColumn<CabinetProperty, String> usedNumColumn = new TableColumn<CabinetProperty, String>("已用");
//		usedNumColumn.setMinWidth(40);
//		usedNumColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("usedNum"));

//		TableColumn<CabinetProperty, String> errorNumColumn = new TableColumn<CabinetProperty, String>("故障");
//		errorNumColumn.setMinWidth(40);
//		errorNumColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("errorNum"));

		TableColumn<CabinetProperty, String> comPortColumn = new TableColumn<CabinetProperty, String>("端口");
		comPortColumn.setMinWidth(40);
		comPortColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("comPort"));
		comPortColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		comPortColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					try {
						int port=Integer.parseInt(event.getNewValue());
						Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
						if (cabinet != null) {
							cabinet.setComPort(port);
							cabinet.update();
							event.getRowValue().setComPort(port+"");
						}
					}catch (Exception e) {
						LayerUtil.open("端口必须数字", 110);
						event.getRowValue().setComPort(event.getOldValue());
						boxTableView.refresh();
					}
				}
			}
		});

		TableColumn<CabinetProperty, String> baudRateColumn = new TableColumn<CabinetProperty, String>("波特率");
		baudRateColumn.setMinWidth(40);
		baudRateColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("baudRate"));
		baudRateColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		baudRateColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					try {
						int baudRate=Integer.parseInt(event.getNewValue());
						Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
						if (cabinet != null) {
							cabinet.setBaudRate(baudRate);
							cabinet.update();
							event.getRowValue().setBaudRate(baudRate+"");
						}
					}catch (Exception e) {
						LayerUtil.open("波特率必须数字", 110);
						event.getRowValue().setBaudRate(event.getOldValue());
						boxTableView.refresh();
					}
				}
			}
		});


		TableColumn<CabinetProperty, String> sortColumn = new TableColumn<CabinetProperty, String>("序号");
		sortColumn.setMinWidth(20);
		sortColumn.setCellValueFactory(new PropertyValueFactory<CabinetProperty, String>("sort"));
		sortColumn.setCellFactory(TextFieldTableCell.<CabinetProperty>forTableColumn());
		sortColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<CabinetProperty, String>>() {
			public void handle(CellEditEvent<CabinetProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					try {
						Cabinet cabinet = Cabinet.dao.findById(event.getRowValue().getId());
						if (cabinet != null) {
							cabinet.setSort(Integer.parseInt(event.getNewValue()));
							cabinet.update();
							event.getRowValue().setSort(event.getNewValue());
						}
					} catch (Exception e) {
						LayerUtil.open("序号必须是数字！", 110);
						event.getRowValue().setSort(event.getOldValue());
						boxTableView.refresh();
					}
				}
			}
		});
		
		boxTableView.getColumns().addAll(nameColumn, codeColumn, typeColumn, totalColumn, comPortColumn, baudRateColumn, sortColumn);
		boxTableView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<CabinetProperty>() {
			public void changed(ObservableValue<? extends CabinetProperty> observable, CabinetProperty oldValue,
					CabinetProperty newValue) {
				if(newValue!=null) {
					refreshBoard(newValue.getId());
				}
			}
		});
		
		/*****************************板块*********************************/
		
		boardTableView.setEditable(true);

		TableColumn<BoardProperty, String> boardIdColumn = new TableColumn<BoardProperty, String>("标识");
		boardIdColumn.setMinWidth(100);
		boardIdColumn.setCellValueFactory(new PropertyValueFactory<BoardProperty, String>("id"));
		boardIdColumn.setVisible(false);

		TableColumn<BoardProperty, String> boardNoColumn = new TableColumn<BoardProperty, String>("版号");
		boardNoColumn.setMinWidth(100);
		boardNoColumn.setCellValueFactory(new PropertyValueFactory<BoardProperty, String>("boardNo"));
		boardNoColumn.setCellFactory(TextFieldTableCell.<BoardProperty>forTableColumn());
		boardNoColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<BoardProperty, String>>() {
			public void handle(CellEditEvent<BoardProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					try {
						Board coard = Board.dao.findById(event.getRowValue().getId());
						if (coard != null) {
							coard.setBoardNo(Integer.parseInt(event.getNewValue()));
							coard.update();
							event.getRowValue().setBoardNo(event.getNewValue());
						}
					} catch (Exception e) {
						LayerUtil.open("板号必须是数字！", 110);
						event.getRowValue().setBoardNo(event.getOldValue());
						boardTableView.refresh();
					}
				}
			}
		});


		TableColumn<BoardProperty, String> boxTotalColumn = new TableColumn<BoardProperty, String>("总数");
		boxTotalColumn.setMinWidth(60);
		boxTotalColumn.setCellValueFactory(new PropertyValueFactory<BoardProperty, String>("boxTotal"));
		boxTotalColumn.setCellFactory(TextFieldTableCell.<BoardProperty>forTableColumn());
		boxTotalColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<BoardProperty, String>>() {
			public void handle(CellEditEvent<BoardProperty, String> event) {
				if (!StrKit.equals(event.getNewValue(), event.getOldValue())) {
					try {
						Board coard = Board.dao.findById(event.getRowValue().getId());
						if (coard != null) {
							coard.setBoxTotal(Integer.parseInt(event.getNewValue()));
							coard.update();
							refreshBoard(coard.getCabinetId());
							update(coard.getCabinetId());
							event.getRowValue().setBoxTotal(event.getNewValue());
						}
					} catch (Exception e) {
						LayerUtil.open("必须是数字！", 110);
						event.getRowValue().setBoxTotal(event.getOldValue());
						boardTableView.refresh();
					}
				}
			}
		});
		
		
		
		boardTableView.getColumns().addAll(boardNoColumn, boxTotalColumn);
		boardTableView.setItems(boardData);

		ProgressStage.of(RouteUtil.mainStage, new Task<Void>() {
			@Override
			protected Void call() throws Exception {
				Platform.runLater(new Runnable() {
					public void run() {
						List<Cabinet> cabinets = Cabinet.dao
								.find("select * from " + Cabinet.TABLE_NAME + " order by sort ");
						if (cabinets != null && cabinets.size() > 0) {
							for (Cabinet cabinet : cabinets) {
								data.add(new CabinetProperty(cabinet));
							}
						}

						boxTableView.setItems(data);
						if(!isDestroy) {
							rotateTransitionOut = new RotateTransition(Duration.seconds(10), timerOutLinePane);
							rotateTransitionOut.setFromAngle(0);
							rotateTransitionOut.setToAngle(360);
							rotateTransitionOut.setByAngle(360); // 设置旋转的角度
							rotateTransitionOut.setCycleCount(Animation.INDEFINITE); // 设置旋转次数，我们需要旋转无数次
							rotateTransitionOut.setInterpolator(Interpolator.LINEAR);
							rotateTransitionOut.play();

							rotateTransitionIn = new RotateTransition(Duration.seconds(10), timerInLinePane);
							rotateTransitionIn.setFromAngle(360);
							rotateTransitionIn.setToAngle(0);
							rotateTransitionIn.setByAngle(360); // 设置旋转的角度
							rotateTransitionIn.setCycleCount(Animation.INDEFINITE); // 设置旋转次数，我们需要旋转无数次
							rotateTransitionIn.setInterpolator(Interpolator.LINEAR);
							rotateTransitionIn.play();
							startCountDown();
						}
					}
				});
				return null;
			}
		}, "查询配置中...").show();

	}
	
	public void refresh() {
		data.clear();
		ProgressStage.of(RouteUtil.mainStage, new Task<Void>() {
			@Override
			protected Void call() throws Exception {
				Platform.runLater(new Runnable() {
					public void run() {
						List<Cabinet> cabinets = Cabinet.dao
								.find("select * from " + Cabinet.TABLE_NAME + " order by sort ");
						if (cabinets != null && cabinets.size() > 0) {
							for (Cabinet cabinet : cabinets) {
								data.add(new CabinetProperty(cabinet));
							}
						}
					}
				});
				return null;
			}
		}, "查询配置中...").show();
	}

	public void add(ActionEvent event) {
		Button bu = (Button) event.getSource();
		bu.setVisible(false);
		Cabinet cabinet = new Cabinet();
		cabinet.setId(UuidUtil.getUUID());
		cabinet.setName("未命名");
		cabinet.setCode("");
		cabinet.setType("1");
		cabinet.setTotal(60);
		cabinet.setComPort(1);
		cabinet.setBaudRate(9600);
		cabinet.setSort(0);
		if (cabinet.save()) {
			data.add(new CabinetProperty(cabinet));
		}
		bu.setVisible(true);
	}

	public void delete(ActionEvent event) {
		Button bu = (Button) event.getSource();
		bu.setVisible(false);
		CabinetProperty cabinetProperty = boxTableView.getSelectionModel().getSelectedItem();
		if (cabinetProperty != null) {
			if (Cabinet.dao.deleteById(cabinetProperty.getId())) {
				LayerUtil.open("删除成功！", 200);
				data.remove(cabinetProperty);
				List<Board> boards = Board.dao
						.find("select * from " + Board.TABLE_NAME + " where cabinetId=?  order by boardNo ",cabinetProperty.getId());
				if (boards != null && boards.size() > 0) {
					for (Board board : boards) {
						board.delete();
					}
				}
			} else {
				LayerUtil.open("删除失败！", 500);
			}
		} else {
			LayerUtil.open("请选择行！", 110);
		}
		bu.setVisible(true);
	}
	
	public void addBoard(ActionEvent event) {
		Button bu = (Button) event.getSource();
		bu.setVisible(false);
		CabinetProperty cabinetProperty = boxTableView.getSelectionModel().getSelectedItem();
		if (cabinetProperty != null) {
			Board board = new Board();
			board.setId(UuidUtil.getUUID());
			board.setCabinetId(cabinetProperty.getId());
			board.setBoardNo(0);
			board.setBoxTotal(20);
			if (board.save()) {
				boardData.add(new BoardProperty(board));
			}
		} else {
			LayerUtil.open("请选择需要添加板块的柜子！", 110);
		}
		bu.setVisible(true);
	}

	public void deleteBoard(ActionEvent event) {
		Button bu = (Button) event.getSource();
		bu.setVisible(false);
		BoardProperty boardProperty = boardTableView.getSelectionModel().getSelectedItem();
		if (boardProperty != null) {
			if (Board.dao.deleteById(boardProperty.getId())) {
				LayerUtil.open("删除成功！", 200);
				boardData.remove(boardProperty);
			} else {
				LayerUtil.open("删除失败！", 500);
			}
		} else {
			LayerUtil.open("请选择行！", 110);
		}
		bu.setVisible(true);
	}
	
	
	public void update(String cabinetId) {
		int total=0;
		List<Board> boards = Board.dao.find("select * from " + Board.TABLE_NAME + " where cabinetId=?  order by boardNo ",cabinetId);
		if (boards != null && boards.size() > 0) {
			for (Board board : boards) {
				total+=board.getBoxTotal();
			}
		}
		Cabinet cabinet=Cabinet.dao.findById(cabinetId);
		if(cabinet!=null) {
			cabinet.setTotal(total);
			cabinet.update();
			refresh();
		}
	}
	
	public void refreshBoard(final String cabinetId) {
		boardData.clear();
		ProgressStage.of(RouteUtil.mainStage, new Task<Void>() {
			@Override
			protected Void call() throws Exception {
				Platform.runLater(new Runnable() {
					public void run() {
						List<Board> boards = Board.dao
								.find("select * from " + Board.TABLE_NAME + " where cabinetId=?  order by boardNo ",cabinetId);
						if (boards != null && boards.size() > 0) {
							for (Board board : boards) {
								boardData.add(new BoardProperty(board));
							}
						}
					}
				});
				return null;
			}
		}, "查询柜子板卡中...").show();
	}

	public void startCountDown() {
		animation = new Timeline(new KeyFrame(Duration.millis(1000), new EventHandler<ActionEvent>() {
			public void handle(ActionEvent event) {
				if(RouteUtil.getTime()>0) {
					RouteUtil.setTime(RouteUtil.getTime() - 1);
					if (RouteUtil.getTime() == 0) {
						timerLabel.setText("0");
						LayerUtil.open("操作超时！", 999);
					} else if (RouteUtil.getTime() > 0) {
						timerLabel.setText(RouteUtil.getTime() + "");
					}
				}
				
			}
		}));
		animation.setCycleCount(Timeline.INDEFINITE);
		animation.play();
	}

	public void destroy() {
		if (animation != null) {
			animation.stop();
		}
		if (rotateTransitionOut != null) {
			rotateTransitionOut.stop();
		}
		if (rotateTransitionIn != null) {
			rotateTransitionIn.stop();
		}
	}

	public void exit(ActionEvent event) {
		if(!isDestroy) {
			isDestroy=true;
			Button bu = (Button) event.getSource();
			bu.setVisible(false);
			destroy();
			RouteUtil.goConfig();
		}
	}

}
